/**
`webpack-tapable` 是一个用于构建可扩展的插件系统的库，它是 Webpack 插件架构的核心部分。通过 `webpack-tapable`，开发者可以创建插件，扩展 Webpack 的功能。
  1. 什么是 `webpack-tapable`？
  `webpack-tapable` 是一个独立的库，提供了一种简单的方法来创建可插拔的事件系统。它允许开发者在特定的生命周期事件上“钩住”功能，从而实现插件的扩展。

  2. 核心概念
  `webpack-tapable` 的核心概念是“钩子”（Hooks）。钩子是一个可以被“钩住”的点，插件可以在这些点上注册回调函数，以便在特定事件发生时执行。

  3. 常用钩子类型
  `webpack-tapable` 支持多种类型的钩子，常见的有：

  - **SyncHook**: 同步钩子，所有注册的回调函数会按顺序执行，返回值会被传递给下一个回调。
  - **AsyncHook**: 异步钩子，允许在回调中使用异步操作。
  - **WaterfallHook**: 瀑布钩子，前一个回调的返回值会作为下一个回调的输入。
  - **BailoutHook**: 提前退出的钩子，允许在某个条件下提前停止执行后续的回调。

  4. 使用示例
  以下是一个简单的示例，演示如何使用 `webpack-tapable` 创建一个自定义插件。

   1. 安装 `webpack-tapable`
  如果你希望单独使用 `webpack-tapable`，可以通过 npm 安装：


  ```bash
  npm install webpack-tapable --save-dev
  ```


   2. 创建自定义插件
  创建一个自定义插件，使用 `SyncHook` 来处理某个事件。

  ```javascript
  const { SyncHook } = require('tapable');

  class MyPlugin {
      constructor() {
          this.hook = new SyncHook(['arg1', 'arg2']); // 创建一个同步钩子
      }

      apply(compiler) {
          // 注册一个钩子
          this.hook.tap('MyPlugin', (arg1, arg2) => {
              console.log('MyPlugin Hook Triggered:', arg1, arg2);
          });

          // 在 Webpack 编译过程中调用钩子
          compiler.hooks.emit.tap('MyPlugin', (compilation) => {
              this.hook.call('value1', 'value2'); // 触发钩子
          });
      }
  }

  module.exports = MyPlugin;
  ```

   3. 在 Webpack 配置中使用插件
  在 Webpack 配置文件中使用自定义插件。

  ```javascript
  const MyPlugin = require('./MyPlugin');

  module.exports = {
      // ...其他配置
      plugins: [
          new MyPlugin(), // 使用自定义插件
      ],
  };
  ```

  5. 注意事项
  - **性能**: 使用钩子时要注意性能，避免在钩子中执行耗时的操作。
  - **异步处理**: 如果使用异步钩子，确保正确处理异步操作的回调。
  - **文档**: 在使用 `webpack-tapable` 时，参考官方文档可以获得更详细的 API 信息和使用示例。

  总结
  `webpack-tapable` 是 Webpack 插件系统的核心，通过钩子机制，开发者可以轻松扩展 Webpack 的功能。通过创建自定义插件并使用不同类型的钩子，开发者可以在特定事件上注册回调，从而实现灵活的功能扩展。希望这个总结对你理解 `webpack-tapable` 的使用有所帮助！
 */
const { SyncHook } = require("tapable");

class Compiler {
  constructor() {
    this.hook = {
      // 1.创建hooks: SyncHook的特点是同步执行，不关心返回值
      syncHook: new SyncHook(["name", "age"]),
    };

    // 2.用hooks监听事件(自定义plugin)
    this.hook.syncHook.tap("event1", (name, age) => {
      console.log("event1:", name, age);
    });

    this.hook.syncHook.tap("event2", (name, age) => {
      console.log("event2:", name, age);
    });
  }
}

const compiler = new Compiler();
setTimeout(() => {
  compiler.hook.syncHook.call("zhangsan", 18);
}, 2000);
